<script setup>
import { onMounted, reactive, ref, useTemplateRef, watch } from 'vue'
import ProblemPreview from '@/views/problem/ProblemPreview.vue'
import { useRoute } from 'vue-router'
import Request from '@/api/axios'
import { useUserStore } from '@/stores/user.ts'
import { CodeStore } from '@/stores/codecache.ts'
import { storeToRefs } from 'pinia'
import { message } from 'ant-design-vue'
import { defineAsyncComponent } from 'vue'
import { useRouter } from 'vue-router'
import { HttpStatusCode } from 'axios'
import { useLocalStorage } from '@/utils/useLocalStorage'
import Setting from '@/views/problem/components/SettingsView.vue'
import Solution from '@/views/problem/components/SolutionView.vue'
const router = useRouter()
// const codeEditor = defineAsyncComponent(() => import('@/components/MonacoEditor/Monaco.vue'))
const codeEditor = defineAsyncComponent(() => import('@/components/AceEditor/AceEditorV2.vue'))
const route = useRoute()
const problem_id = route.params.id

const userStore = useUserStore()
const { id } = storeToRefs(userStore)
const codeStore = CodeStore()
const { addCodeStore, removeCodeStore, getCodeStore } = codeStore
const code = ref('')
onMounted(() => code.value = getCodeStore(`problem-${problem_id}-${id.value}`) ?? '')
const Language = useLocalStorage('language', 'cpp')
const Theme = useLocalStorage('editor_theme', 'vs-dark')
const problem = reactive({
    title: '',
    context: '',
    input_description: '',
    output_description: '',
    created_by: '',
    tip: '',
    judge_config: {},
    judge_sample: []
})
const updateProblemInfo = (data) => {
    problem.title = data.title
    problem.context = data.context
    problem.input_description = data.input_description
    problem.output_description = data.output_description
    problem.created_by = data.username
    problem.judge_config = data.judge_config
    problem.judge_sample = data.judge_sample
    problem.tip = data.tip
}
const loadingProblem = ref(true)
const loadingSubmit = ref(false)
const loadingTest = ref(false)
onMounted(async () => {
    await Request.get({
        url: `/problem/${problem_id}`
    })
        .then((response) => {
            if (response.code === HttpStatusCode.NotFound) {
                router.push({ name: '404' })
                return
            }
            updateProblemInfo(response.info)
        })
        .catch((err) => {
            message.error("出错啦")
            console.log(err)
        }).finally(() => {
            loadingProblem.value = false
        })
})
const handleEditorChange = (newValue) => {
    code.value = newValue
    addCodeStore(`problem-${problem_id}-${id.value}`, newValue)
}
const handleRefresh = () => {
    removeCodeStore(`problem-${problem_id}-${id.value}`)
    code.value = ''
}
const test_case = ref({
    input: '',
    output: '',
    expected: ''
})
const language_transform = (language) => {
    switch (language) {
        case 'c_cpp':
            return 'cpp';
        case 'python':
        case 'python2':
            return 'python';
        case 'javascript':
            return 'javascript';
        default:
            return language;
    }
};
import { notification } from 'ant-design-vue';
const openNotification = (placement, description, record_id) => {
    notification.info({
        message: "消息",
        description:
            '结果：' + description + '，点击通知查看代码运行详情',
        placement,
        onClick: () => {
            router.push({ name: 'record', params: { id: record_id } })
        },
    });
};
const supported_languages = ['c', 'cpp', 'python2']
const SubmitCode = async () => {
    const language = language_transform(Language.value)
    if (!supported_languages.includes(language)) {
        message.error('暂不支持该语言,努力中...')
        return
    };
    loadingSubmit.value = true
    await Request.post({
        url: `/problem/submit`,
        data: {
            problem_id: problem_id,
            user_id: id.value,
            code: code.value,
            language,
        }
    })
        .then((res) => {
            loadingSubmit.value = false
            openNotification('topRight', res.info.verdict, res.info.submission_id)
        })
        .catch((err) => {
            message.error("出错啦")
            console.log(err)
        })
}
const languageOptions = ref([])
const themeOptions = ref([])

const settingVisiable = ref(false)
const solutionVisiable = ref(false)
import loading from '@/ui/Loading.vue'
import EditorHeader from './components/EditorHeader.vue'
import SubmitFooter from './components/SubmitFooter.vue'
const footerResizable = ref(false)
const footerSize = ref()

const testCode = async () => {
    const language = language_transform(Language.value)
    if (!supported_languages.includes(language)) {
        message.error('暂不支持该语言,努力中...')
        return
    };
    loadingTest.value = true
    test_case.value.output = ''
    await Request.post({
        url: `/ide/submit`,
        data: {
            submission_id: 123456789,
            code: code.value,
            language: language,
            test_cases: [{
                case_id: 1,
                stdin: test_case.value.input,
                expected: test_case.value.expected,
            }],
            message: "",
            seccomp_profile: "",
            resources_limits: {
                cpu_time: 100000,
                memory_bytes: 67108864,
                stack_bytes: 10485760,
                output_bytes: 10485760,
            }
        },
        timeout: 10 * 1000 // 60 sec
    })
        .then((res) => {
            if (res.info.verdict == "CompilationError") {
                test_case.value.output = res.info.result[0].stderr ?? ''
            }
            if (res.info.verdict == "WrongAnswer") {
                res.info.result.forEach((item, index) => {
                    test_case.value.output = item.stdout ?? item.stderr ?? ''
                })
            }
        })
        .catch((err) => {
            console.log(err)

        })
        .finally(() => (loadingTest.value = false))
}
</script>
<template>
    <div class="problem-container">
        <el-skeleton :loading="loadingProblem" animated>
            <template #template>
                <loading />
            </template>
            <template #default>
                <el-splitter>
                    <el-splitter-panel size="50%">
                        <div class="left">
                            <ProblemPreview class="problem-preview" :Title="problem.title" :Context="problem.context"
                                :InputDescription="problem.input_description"
                                :OutputDescription="problem.output_description" :CreatedBy="problem.created_by"
                                :JudgeSample="problem.judge_sample" :JudgeConfig="problem.judge_config"
                                :Tip="problem.tip" />
                        </div>
                    </el-splitter-panel>
                    <el-splitter-panel :min="200" size="50%">
                        <div class="right">
                            <el-splitter layout="vertical">
                                <el-splitter-panel>
                                    <EditorHeader :languageOptions="languageOptions" v-model:language="Language"
                                        @openSetting="() => settingVisiable = true"
                                        @openSolution="() => solutionVisiable = true" />
                                    <keep-alive>
                                        <codeEditor @change="handleEditorChange" v-model:value="code"
                                            @update:languageOptions="($event) => languageOptions = $event.map((i) => { return { value: i, label: i } })"
                                            @update:themeOptions="($event) => themeOptions = $event.map((i) => { return { value: i, label: i } })"
                                            :theme="Theme" :language="Language" />
                                    </keep-alive>
                                </el-splitter-panel>
                                <el-splitter-panel size="10%" min="10%" v-model:size="footerSize"
                                    :resizable="footerResizable">
                                    <SubmitFooter style="width: 100%; height: 100%;" :loadingSubmit="loadingSubmit"
                                        :loadingTest="loadingTest" @submitCode="SubmitCode"
                                        v-model:resizable="footerResizable" v-model:test_case="test_case"
                                        @testCode="testCode" />
                                </el-splitter-panel>
                            </el-splitter>
                        </div>
                        <a-drawer v-model:open="solutionVisiable" style="color: red" size="large" title="题解面板"
                            placement="right">
                            <Solution />
                        </a-drawer>
                        <a-drawer v-model:open="settingVisiable" size="default">
                            <Setting :themeOptions="themeOptions" />
                        </a-drawer>
                    </el-splitter-panel>
                </el-splitter>
            </template>
        </el-skeleton>

    </div>
</template>

<style scoped>
.problem-container {
    height: calc(100vh - 100px);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.left {
    height: 100%;
    overflow-y: auto;
    padding: 0.75rem;
    padding-right: 0;
    background: #ffffff;
    -ms-overflow-style: none;
    scrollbar-width: none;
}

.left::-webkit-scrollbar {
    display: none;
}

.right {
    height: 100%;
    background: #ffffff;
    display: flex;
    flex-direction: column;
}

.problem-preview {
    height: 100%;
}

:deep(.el-splitter) {
    height: 100%;
}

:deep(.el-splitter-panel) {
    overflow: hidden;
}

:deep(.el-splitter__bar) {
    background-color: #e8e8e8;
}

:deep(.el-splitter__bar:hover) {
    background-color: #1890ff;
}
</style>
